home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / misc / emu / arosdev.lha / AROS / rom / utility / packstructuretags.c < prev    next >
C/C++ Source or Header  |  1997-02-03  |  6KB  |  180 lines

  1. /*
  2.     Copyright (C) 1995-1997 AROS - The Amiga Replacement OS
  3.     $Id: packstructuretags.c,v 1.4 1997/02/03 02:58:31 ldp Exp $
  4.  
  5.     Desc: Pack a TagList into a structure.
  6.     Lang: english
  7. */
  8. #include "utility_intern.h"
  9.  
  10. /*****************************************************************************
  11.  
  12.     NAME */
  13. #include <utility/tagitem.h>
  14. #include <utility/pack.h>
  15. #include <proto/utility.h>
  16.  
  17.         AROS_LH3(ULONG, PackStructureTags,
  18.  
  19. /*  SYNOPSIS */
  20.         AROS_LHA(APTR            , pack, A0),
  21.         AROS_LHA(ULONG          *, packTable, A1),
  22.         AROS_LHA(struct TagItem *, tagList, A2),
  23.  
  24. /*  LOCATION */
  25.         struct Library *, UtilityBase, 35, Utility)
  26.  
  27. /*  FUNCTION
  28.         This function will scan through the packTable, and for each TagItem
  29.         described in a packTable entry which can be found in the tagList,
  30.         the data in the TagItem's ti_Data field will be packed into the
  31.         structure as described in the packTable.
  32.  
  33.     INPUTS
  34.         pack            -   The structure to fill in.
  35.         packTable       -   Table describing how to pack the structure.
  36.                             See the include file utility/pack.h for
  37.                             information on the format of this table.
  38.         tagList         -   List of TagItems containing data.
  39.  
  40.     RESULT
  41.         The number of TagItems packed.
  42.  
  43.     NOTES
  44.  
  45.     EXAMPLE
  46.  
  47.     BUGS
  48.  
  49.     SEE ALSO
  50.         UnpackStructureTags()
  51.  
  52.     INTERNALS
  53.  
  54.     HISTORY
  55.         29-10-95    digulla automatically created from
  56.                             utility_lib.fd and clib/utility_protos.h
  57.  
  58. *****************************************************************************/
  59. {
  60.     AROS_LIBFUNC_INIT
  61.     AROS_LIBBASE_EXT_DECL(struct UtilityBase *, UtilityBase)
  62.  
  63.     Tag         tagBase;
  64.     UWORD       memOff;
  65.     UWORD       tagOff;
  66.     UBYTE       bitOff;
  67.     struct TagItem *ti;
  68.     LONG        count = 0;
  69.  
  70.     tagBase = *packTable++;
  71.     for( ; *packTable != 0; packTable++)
  72.     {
  73.         /* New base tag */
  74.         if(*packTable == -1)
  75.         {
  76.             tagBase = *++packTable;
  77.             continue;
  78.         }
  79.  
  80.         /* This entry is not defined for packing */
  81.         if((*packTable & PSTF_PACK))    continue;
  82.  
  83.         tagOff = (*packTable >> 16) & 0x3FF;
  84.  
  85.         /* Does the tag we are interested in exist in that list. */
  86.         ti = FindTagItem(tagBase + tagOff, tagList);
  87.         if(ti == NULL)
  88.             continue;
  89.  
  90.         memOff = *packTable & 0x1FFF;
  91.         bitOff = (*packTable & 0xE000) >> 13;
  92.  
  93.         /*
  94.             If the PSTF_EXISTS bit is 1, then the tagexists says that we
  95.             set the bit to 1.
  96.  
  97.             XXX: Have to see what happens when the Tag doesn't exist.
  98.         */
  99.         if((*packTable & (PKCTRL_BIT|PSTF_EXISTS)) == (PKCTRL_BIT|PSTF_EXISTS))
  100.         {
  101.             /* If the PSTF_SIGNED bit is 1, then this is actually FLIPBIT */
  102.             if(*packTable & PSTF_SIGNED)
  103.                 *(UBYTE *)&((UBYTE *)pack)[memOff] &= ~(1 << bitOff);
  104.             else
  105.                 *(UBYTE *)&((UBYTE *)pack)[memOff] |= (1 << bitOff);
  106.  
  107.             count++;
  108.             continue;
  109.         }
  110.  
  111.         /*
  112.             I need this rather interesting casting because the offset
  113.             is always in bytes, but the cast to (ULONG *) etc, will cause
  114.             the array indexing to be done in different sizes, so I basically
  115.             override that, then cast to the required size. I've got to cast
  116.             like: &((UBYTE *)pack)[memOff],
  117.             not:  (UBYTE *)&pack[memOff]
  118.             because otherwise I'd be dereferencing a void *.
  119.  
  120.             Ah, so much easier in assembly eh?
  121.  
  122.             Also the assigning is different for signed and unsigned since
  123.             ti_Data is not necessarily the same size as the structure field,
  124.             so we have to let the compiler do sign extension.
  125.  
  126.             Bit shifting the packTable entry >> 24, we can do some more
  127.             instruction space efficient stuff.
  128.         */
  129.         switch((*packTable >> 24) & 0x98)
  130.         {
  131.             case (PKCTRL_ULONG >> 24):
  132.                 *(ULONG *)&((UBYTE *)pack)[memOff] = ti->ti_Data;
  133.                 break;
  134.  
  135.             case (PKCTRL_UWORD >> 24):
  136.                 *(UWORD *)&((UBYTE *)pack)[memOff] = ti->ti_Data;
  137.                 break;
  138.  
  139.             case (PKCTRL_UBYTE >> 24):
  140.                 *(UBYTE *)&((UBYTE *)pack)[memOff] = ti->ti_Data;
  141.                 break;
  142.  
  143.             case (PKCTRL_LONG >> 24):
  144.                 *(LONG *)&((UBYTE *)pack)[memOff] = ti->ti_Data;
  145.                 break;
  146.  
  147.             case (PKCTRL_WORD >> 24):
  148.                 *(WORD *)&((UBYTE *)pack)[memOff] = ti->ti_Data;
  149.                 break;
  150.  
  151.             case (PKCTRL_BYTE >> 24):
  152.                 *(BYTE *)&((UBYTE *)pack)[memOff] = ti->ti_Data;
  153.                 break;
  154.  
  155.             case (PKCTRL_BIT >> 24):
  156.                 if(ti->ti_Data)
  157.                     *(UBYTE *)&((UBYTE *)pack)[memOff] |= (1 << bitOff);
  158.                 else
  159.                     *(UBYTE *)&((UBYTE *)pack)[memOff] &= ~(1 << bitOff);
  160.                 break;
  161.  
  162.             case (PKCTRL_FLIPBIT >> 24):
  163.                 if(ti->ti_Data)
  164.                     *(UBYTE *)&((UBYTE *)pack)[memOff] &= ~(1 << bitOff);
  165.                 else
  166.                     *(UBYTE *)&((UBYTE *)pack)[memOff] |= (1 << bitOff);
  167.                 break;
  168.  
  169.             /* We didn't actually pack anything */
  170.             default:
  171.                 count--;
  172.         } /* switch() */
  173.         count++;
  174.     } /* for() */
  175.  
  176.     return count;
  177.  
  178.     AROS_LIBFUNC_EXIT
  179. } /* PackStructureTags */
  180.